<template>
  <div>
    <search-form
      v-if="formOptions"
      ref="searchForm"
      :forms="formOptions.forms"
      :size="formOptions.size"
      :fuzzy="formOptions.fuzzy"
      :inline="formOptions.inline"
      :label-width="formOptions.labelWidth"
      :item-width="formOptions.itemWidth"
      :btn-md="formOptions.btnMd"
      :btn-justify="formOptions.btnJustify"
      :t-header="formOptions.tHeader || formOptions.forms.map(v=>v.label)"
      :filter-val="formOptions.filterVal"
      :list="tableData"
      :url="url"
      :filename="formOptions.filename"
      :submit-handler="searchHandler"
      :submit-loading="tableLoading"
      :show-download-btn="formOptions.showDownloadBtn"
      :show-search-btn="formOptions.showSearchBtn"
      :show-reset-btn="formOptions.showResetBtn"
      :submit-btn-text="formOptions.submitBtnText"
      :reset-btn-text="formOptions.resetBtnText"
      @reset="$emit('reset')"
    >
      <slot slot="btn" name="btn" />
    </search-form>

    <slot :loading="tableLoading" :search="searchHandler" name="form" />

    <slot />

    <el-table
      v-loading.lock="tableLoading"
      ref="table"
      :data="tableData"
      :border="border"
      :size="size"
      :stripe="stripe"
      :height="height"
      :max-height="maxHeight"
      :fit="fit"
      :show-header="showHeader"
      :highlight-current-row="highlightCurrentRow"
      :current-row-key="currentRowKey"
      :row-style="rowStyle"
      :row-key="rowKey"
      :empty-text="emptyText"
      :default-expand-all="defaultExpandAll"
      :expand-row-keys="expandRowKeys"
      :default-sort="defaultSort"
      :tooltip-effect="tooltipEffect"
      :show-summary="showSummary"
      :sum-text="sumText"
      :summary-method="summaryMethod"
      :style="tableStyle"
      :row-class-name="tableRowClassName"
      header-row-class-name="table-header"
      @select="(selection, row) => emitEventHandler('select', selection, row)"
      @select-all="selection => emitEventHandler('select-all', selection)"
      @selection-change="selection => emitEventHandler('selection-change', selection)"
      @cell-mouse-enter="(row, column, cell, event) => emitEventHandler('cell-mouse-enter', row, column, cell, event)"
      @cell-mouse-leave="(row, column, cell, event) => emitEventHandler('cell-mouse-leave', row, column, cell, event)"
      @cell-click="(row, column, cell, event) => emitEventHandler('cell-click', row, column, cell, event)"
      @cell-dblclick="(row, column, cell, event) => emitEventHandler('cell-dblclick', row, column, cell, event)"
      @row-click="(row, event, column) => emitEventHandler('row-click', row, event, column)"
      @row-dblclick="(row, event) => emitEventHandler('row-dblclick', row, event)"
      @row-contextmenu="(row, event) => emitEventHandler('row-contextmenu', row, event)"
      @header-click="(column, event) => emitEventHandler('header-click', column, event)"
      @sort-change="args => emitEventHandler('sort-change', args)"
      @filter-change="filters => emitEventHandler('filter-change', filters)"
      @current-change="(currentRow, oldCurrentRow) => emitEventHandler('current-change', currentRow, oldCurrentRow)"
      @header-dragend="(newWidth, oldWidth, column, event) => emitEventHandler('header-dragend', newWidth, oldWidth, column, event)"
      @expand-change="(row, expanded) => emitEventHandler('expand-change', row, expanded)">

      <slot name="prepend" />

      <el-table-column
        v-for="(column, columnIndex) in columns"
        :key="columnIndex"
        :column-key="column.columnKey"
        :prop="column.prop"
        :label="$t(column.label)"
        :min-width="column.minWidth || flexColumnWidth(column.label) || column.width || 150"
        :fixed="column.fixed || (columnIndexFix && columnIndex == 0)"
        :render-header="column.renderHeader"
        :sortable="column.sortable"
        :sort-by="column.sortBy"
        :sort-method="column.method"
        :resizable="column.resizable"
        :formatter="column.formatter"
        :show-overflow-tooltip="column.showOverflowTooltip"
        :align="column.align || 'center'"
        :header-align="column.headerAlign || column.align"
        :class-name="column.className"
        :label-class-name="column.labelClassName"
        :selectable="column.selectable"
        :reserve-selection="column.reserveSelection"
        :filters="column.filters"
        :filter-placement="column.filterPlacement"
        :filter-multiple="column.filterMultiple"
        :filter-method="column.filterMethod"
        :filtered-value="column.filteredValue"
        width="-">
        <template slot-scope="scope" :scope="newSlotScope ? 'scope' : false ">
          <span v-if="column.filter">
            {{
            Vue.filter(column['filter'].split('|')[0])(
              scope.row[column.prop],

              column['filter'].split('|')[1] ? column['filter'].split('|')[1].split(',')[0] : null,

              column['filter'].split('|')[1] && column['filter'].split('|')[1].split(',')[1] ? column['filter'].split('|')[1].split(',')[1] : null,

              column['filter'].split('|')[1] && column['filter'].split('|')[1].split(',')[2] ? column['filter'].split('|')[1].split(',')[2] : null,

              column['filter'].split('|')[1] && column['filter'].split('|')[1].split(',')[3] ? column['filter'].split('|')[1].split(',')[3] : null
            )
            }}
          </span>
          <span v-else-if="column.slotName">
            <slot :name="column.slotName" :row="scope.row" :$index="scope.$index" />
          </span>
          <span v-else-if="column.render">
            {{ column.render(scope.row) }}
          </span>
          <span v-else-if="column.formatter">
            {{ column.formatter(scope.row, scope.column, scope.row[column.prop], scope.$index) }}
          </span>
          <span v-else>
            {{ scope.row[column.prop] }}
          </span>
        </template>
      </el-table-column>

      <slot name="append" />
      <template slot="empty">
        <svg-icon style="width:50px;height:50px;margin-top:30px" icon-class="no-data" />
        <p>暂无数据</p>
      </template>

    </el-table>

    <div v-if="showPagination" style="margin-top: 10px;text-align: right;">
      <el-pagination :current-page="pagination.pageIndex" :page-sizes="pageSizes" :page-size="pagination.pageSize" :layout="paginationLayout" :total="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
    </div>
  </div>
</template>

<script>
/* eslint-disable */
import Vue from 'vue'
import props from './props'
import searchForm from '@/components/Form/index.vue'
import request from '@/utils/request'

export default {
  name: 'ElSearchTablePagination',
  components: {
    searchForm
  },
  props,
  data() {
    const _this = this
    return {
      Vue,
      pagination: {
        pageIndex: 1,
        pageSize: (() => {
          const { pageSizes } = _this
          if (pageSizes.length > 0) {
            return pageSizes[0]
          }
          return 20
        })()
      },
      total: 0,
      tableData: [],
      tableLoading: false,
      cacheLocalData: []
    }
  },
  computed: {
    newSlotScope() {
      return Number(Vue.version.replace(/\./g, '')) >= 250
    },
    lang() {
      return this.$store.getters.language
    }
  },
  watch: {
    data: function(value) {
      this.loadLocalData(value)
    },
    loading: function(value) {
      this.tableLoading = value
    }
  },
  mounted() {
    // event: expand changed to `expand-change` in Element v2.x
    this.$refs['table'].$on('expand', (row, expanded) => this.emitEventHandler('expand', row, expanded))
    const { autoLoad, formOptions, params } = this
    if (autoLoad) {
      if (formOptions) {
        this.$refs['searchForm'].getParams((error, formParams) => {
          if (!error) {
            this.fetchHandler(Object.assign(formParams, params))
          }
        })
      } else {
        this.fetchHandler(params)
      }
    }
  },
  methods: {
    clearSelection() {
      this.$refs.table.clearSelection()
    },
    tableRowClassName({row, rowIndex}) {
      if (rowIndex % 2 === 1) {
        return 'warning-row';
      } else  {
        return 'success-row';
      }
      return '';
    },
    flexColumnWidth(str) {
      let flexWidth = 0
      for (const char of str) {
        if ((char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z')) {
          // 如果是英文字符，为字符分配8个单位宽度
          flexWidth += 10
        } else if (char >= '\u4e00' && char <= '\u9fa5') {
          // 如果是中文字符，为字符分配20个单位宽度
          flexWidth += 22
        } else {
          // 其他种类字符，为字符分配5个单位宽度
          flexWidth += 5
        }
      }
      if (flexWidth < 50) {
        // 设置最小宽度
        flexWidth = 200
      }
      // if (flexWidth > 250) {
      //   // 设置最大宽度
      //   flexWidth = 250
      // }
      return flexWidth
    },
    handleSizeChange(size) {
      this.pagination.pageSize = size
      this.dataChangeHandler()
    },
    handleCurrentChange(pageIndex) {
      this.pagination.pageIndex = pageIndex
      this.dataChangeHandler()
    },
    searchHandler(resetPageIndex = true) {
      if (resetPageIndex) {
        this.pagination.pageIndex = 1
      }
      this.$emit('reset')
      this.dataChangeHandler(arguments[0])
    },
    dataChangeHandler() {
      const { type } = this
      if (type === 'local') {
        this.fetchHandler(arguments[0])
      }
    },
    dataFilter(data) {
      const { pageIndex, pageSize } = this.pagination
      return data.filter((v, i) => {
        return i >= (pageIndex - 1) * pageSize && i < pageIndex * pageSize
      })
    },
    dataFilterHandler(formParams) {
      const { cacheLocalData, params, pagination } = this
      const { pageIndex, pageSize } = pagination
      const mergeParams = Object.assign(params, formParams)
      debugger
      const validParamKeys = Object.keys(mergeParams).filter(v => {
        return mergeParams[v] !== undefined && mergeParams[v] !== ''
      })
      const searchForm = this.$refs['searchForm']
      let paramFuzzy
      if (searchForm) {
        paramFuzzy = searchForm.getParamFuzzy()
      }

      if (validParamKeys.length > 0) {
        const validData = cacheLocalData.filter(v => {
          const valids = []
          validParamKeys.forEach(vv => {
            if (typeof v[vv] === 'number') {
              valids.push(
                paramFuzzy && paramFuzzy[vv] ? (String(v[vv]).indexOf(String(mergeParams[vv])) !== -1)
                  : (String(v[vv]) === String(mergeParams[vv]))
              )
            } else {
              valids.push(
                paramFuzzy && paramFuzzy[vv] ? (v[vv].indexOf(mergeParams[vv]) !== -1) : (v[vv] === mergeParams[vv])
              )
            }
          })
          return valids.every(vvv => {
            return vvv
          })
        })

        this.tableData = this.dataFilter(validData)
        this.total = validData.length
      } else {
        this.total = cacheLocalData.length
        this.tableData = this.dataFilter(cacheLocalData)
      }
    },
    fetchHandler(formParams = {}) {
      this.tableLoading = true
      let { fetch, method, url, $axios, headers,
        listField, totalField, params, showPagination,
        pagination } = this

      for (const key in formParams) {
        if (formParams[key] === '') {
          formParams[key] = undefined
        }
      }
      params = JSON.parse(JSON.stringify(Object.assign(formParams)))
      if (showPagination) {
        params = Object.assign(params, {
          'page': pagination.pageIndex,
          'limit': pagination.pageSize
        })
      }
      this.$emit('searchHandler',params)
      const requestObject = request({
        url,
        method,
        params
      })
      requestObject.then(response => {
        const result = response
        if (this.dataHandler) {
          this.tableData = result.data.items.map(this.dataHandler)
        } else {
          this.tableData = result.data.items
        }
        if(result.data.options) {
          this.$emit('options',result.data.options)
        }
        this.total = result.data.total
        this.tableLoading = false
      }).catch(error => {
        this.tableLoading = false
      })
    },
    emitEventHandler(event) {
      this.$emit(event, ...Array.from(arguments).slice(1))
    },
    loadLocalData(data) {
      const { autoLoad } = this
      if (!data) {
        throw new Error(`When the type is 'local', you must set attribute 'data' and 'data' must be a array.`)
        this.showPagination = false
        return false
      }
      const cacheData = JSON.parse(JSON.stringify(data.data.items))
      this.cacheLocalData = cacheData
      if (autoLoad) {
        this.pagination.pageIndex = 1
        this.tableData = this.dataFilter(cacheData)
        this.total = data.data.total
      }
    }
  }
}
</script>
<style lang="scss">
  .el-table .success-row {
    background: #f6f9fa;
  }
</style>
